﻿namespace KingerRobot.MexicoSailunMDC.Biz;
/// <summary>
/// 异常口入库任务执行
/// </summary>
public class LineAbnormalExecuteBiz : K8.MDCBB.Biz
{
    private const string ClassName = nameof(LineAbnormalExecuteBiz);


    #region 配置参数
    private ParamData Param { get; set; }

    class ParamData
    {
        /// <summary>
        /// 扫描仪位置ID
        /// </summary>
        public long LineScannerLoc { get; set; }
    }
    #endregion

    #region PLC 通讯参数
    private ValueData Data { get; set; }
    class ValueData
    {
        /// <summary>
        /// 读取任务号（上段线体任务读取后【有值】）才下传新任务
        /// </summary>
        public int WorkNo { get; set; }
        /// <summary>
        /// 0:PLC读取后可改成 0
        /// 1:WCS任务下传完成..............可读可写/WCS读取到 0，下发任务，PLC接收到 1，改为 0。
        /// </summary>
        public int TaskFlag { get; set; }

    }
    #endregion

    #region 缓存
    private CacheData Cache { get; set; }
    class CacheData
    {

    }
    #endregion

    #region 实时日志
    private StepData Step { get; set; }
    class StepData
    {
        private string _msg = string.Empty;
        public string StepMsg
        {
            get
            {
                return this._msg;
            }
            set
            {
                if (string.IsNullOrWhiteSpace(value))
                {
                    this._msg = string.Empty;
                    return;
                }
                this._msg = $"{ClassName}|{System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}>>{value}";
            }
        }
        public int RStatus { get; set; }
    }
    private void StepMsg(string msg)
    {
        this.Step.StepMsg = msg;
        WriteLog(msg);
    }
    #endregion

    #region 文件日志（运行需要 Nlog 配置）
    private void WriteLog(string message)
    {
        K8.LSF.Client.Log(new K8.LSF.Log { Data = message });
    }
    #endregion 

    /// <summary>
    /// 和 PLC 通讯对象
    /// </summary>
    private BizData BizData { get; set; }


    public int Execute(BizData writer)
    {
        // Excute 方法外使用 BizData
        this.BizData = writer;

        // 返回参数
        var result = 0;
        if (Data.TaskFlag == (int)EnumLineAck.WCSDownFinish)
        {
            // 已扫描条码
            this.StepMsg($" {Data.WorkNo}任务下传完成，但PLC未读取成功:{Data.TaskFlag}【PLC读取后可改成 0】");
            return result;
        }
        var startLoc = Param.LineScannerLoc;

        // 获取任务ID
        var taskService = K8.RSF.Client.Create<ITaskService>();
        var task = taskService.GetTaskBeanByExecuteStartLoc(startLoc);
        if (task is null)
        {
            this.StepMsg($"{startLoc} 开始位置未找到可执行指令");
            return result;
        }

        var taskNo = task.TaskNo.GetValueOrDefault();
        if (task.CmdStatus == (int)EnumTaskCmdStatus.Executed)
        {
            this.StepMsg($"任务号：{taskNo}，已执行");
            return result;
        }
        if(task.StartLoc != startLoc)
        {
            this.StepMsg($"开始位置{startLoc}没有可执行任务，任务号：{taskNo}，已执行");
            return result;
        }
        if(task.TaskType != (int)EnumTaskType.Transportation)
        {
            this.StepMsg($"开始位置{startLoc}没有可执行任务类型{task.TaskType}，任务号：{taskNo}，已执行");
            return result;
        }


        // 下发 
        var mark = SetTaskInfo(task);

        if (mark > 0)
        {
            // 任务下传完成，修改标识
            mark = this.SetTaskFlag();
            if (mark > 0)
            {
                // 执行、保存缓存
                var service = K8.RSF.Client.Create<IWarehousingBeforeService>();
                service.ExecuteTask(taskNo, Param.LineScannerLoc);
            }
        }
        return result;
    }

    private int SetTaskInfo(BizTaskBean task)
    {
        var sProductCode = task.ProductCode;
        string destination = task.TargetPlcLoc;

        return this.BizData.WriteData(new
        {
            Destination = destination,              // 目标地址
            WorkNo = task.TaskNo,                   // 流水号
            OutSize = task.OutSize,                 // 外径
            SProductCode = sProductCode,
        });
    }

    private int SetTaskFlag()
    {
        var mark = this.BizData.WriteData(new
        {
            TaskFlag = EnumLineAck.WCSDownFinish,
        });
        Thread.Sleep(100);
        return mark;
    }
}
